package ch.epfl.lara.pm.analyze.set;

import ch.epfl.lara.pm.ast.{Expr,TypeTree,CaseDef}
import ch.epfl.lara.pm.global.ObjectTable

//trait IMatch {
  
  /** Iternal representation for cases of a match expression */
  case class ICaseDef(kase: CaseDef,pset: List[String])
  
  
  sealed abstract class IPatternRefinedDef {
    def getType: Option[TypeTree] = this match {
      case IVarPattern(tpe,_) => Some(tpe)
      case IClassPattern(objname,_,_) => Some(ObjectTable.getExtractorType(objname))
      case IPatternRefined(pattern,_) => pattern.getType
      case IWildcardPattern => None
    }
  }  

  /**
   * IPatternRefined element is the field of an IClassPattern associated with the return type of the extractor
   * of the IClassPattern object.
   */
  case class IPatternRefined(pattern: IPatternRefinedDef, refinement: TypeTree) extends IPatternRefinedDef
  /**
   * Wildcard as intended in Scala don't directly exists in our language. A IWildcardPattern is created
   * when the type information that concern a pattern is too general and so it's not worth to consider it 
   * (as it would be trivially true)
   */
  case object IWildcardPattern extends IPatternRefinedDef
  
  
  
  
  sealed abstract class IPatternDef extends IPatternRefinedDef
  /**
   * IVarPatter is the absolute equivalent of a VarPattern. The name of the pattern is discharged (as it is useless
   * for the set analysis). The path is the absolute path to the pattern.
   */
  case class IVarPattern(tpe: TypeTree, path: String) extends IPatternDef
  
  /**
   * IClassPattern is the absolute equivalent of a ClassPattern. The name of the pattern is discharged (as it is useless
   * for the set analysis). The fields of the pattern are coupled with the return type of the extractor of the Object "objname".
   * The path is the absolute path to the pattern.
   */
  case class IClassPattern(objname: String, ifields: List[IPatternRefinedDef], path: String) extends IPatternDef
//}
